package com.baitiaojun.datasource.core.datasource.aspect;

import com.baitiaojun.common.utils.object.ObjectUtils;
import com.baitiaojun.datasource.core.datasource.DataSourceHolder;
import com.baitiaojun.datasource.core.datasource.annotation.DataSource;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Order(1)
@Aspect
@Component
@Slf4j
public class DataSourceAspect {

    @Pointcut("@annotation(com.baitiaojun.datasource.core.datasource.annotation.DataSource) || " +
            "@within(com.baitiaojun.datasource.core.datasource.annotation.DataSource)")
    public void ds() {

    }

    @Around("ds()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        DataSource annotation = AnnotationUtils.findAnnotation(methodSignature.getMethod(), DataSource.class);
        if(ObjectUtils.isNull(annotation)) {
            annotation = AnnotationUtils.findAnnotation(methodSignature.getDeclaringType(), DataSource.class);
        }
        if (ObjectUtils.isNotNull(annotation)) {
            String dbName = annotation.dataSourceTypeEnums().getName();
            DataSourceHolder.setDb(dbName);
            log.info("&&&&&&&&&&&&&&&&&&&&已切换至新数据源:{}&&&&&&&&&&&&&&&&&&&&&", dbName);
        }
        try {
            return joinPoint.proceed();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        } finally {
            DataSourceHolder.remove();
        }
    }
}
